package xyz.cerberu.cet.global.configuration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;
import xyz.cerberu.cet.global.handler.ReturnValueJsonSerializerHandler;

import javax.annotation.PostConstruct;
import java.util.LinkedList;
import java.util.List;

/**
 * @author β世界
 * Created on 22:36
 * @Description Handler配置器
 */
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
    /** 请求处理的适配器 **/
    @Autowired
    private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
    /** 用于处理json返回的handler **/
    @Autowired
    private ReturnValueJsonSerializerHandler returnValueHandler;

    /**
     * @author β世界 on 12:50 2021/3/25
     * 用于获取原先的handler列表
     * 将旧的添加到新的列表中
     * @return void
     **/
    @PostConstruct
    public void init() {
        // 新的handler列表
        final List<HandlerMethodReturnValueHandler> newHandlers = new LinkedList<>();
        // 原先的handler列表
        final List<HandlerMethodReturnValueHandler> originalHandlers = requestMappingHandlerAdapter.getReturnValueHandlers();
        // 判断原先的列表是否为空
        if (originalHandlers != null) {
            // 将所有的旧列表内容都添加到新的列表中
            newHandlers.addAll(originalHandlers);
            // 获取到RequestResponseBodyMethodProcessor的下标
            // 获取处理器应处于的位置，需要在RequestResponseBodyMethodProcessor之前
            final int index = obtainValueHandlerPosition(originalHandlers, RequestResponseBodyMethodProcessor.class);
            newHandlers.add(index, returnValueHandler);
        } else {
            newHandlers.add(returnValueHandler);
        }

        // 设置返回值handler列表
        requestMappingHandlerAdapter.setReturnValueHandlers(newHandlers);
    }

    /**
     * 获取让自定义处理器生效应处于的位置
     * @param originalHandlers 已经添加的返回值处理器
     * @param handlerClass     返回值处理器的类型
     * @return 自定义处理器需要的位置
     */
    private int obtainValueHandlerPosition(final List<HandlerMethodReturnValueHandler> originalHandlers, Class<?> handlerClass) {
        for (int i = 0; i < originalHandlers.size(); i++) {
            final HandlerMethodReturnValueHandler valueHandler = originalHandlers.get(i);
            if (handlerClass.isAssignableFrom(valueHandler.getClass())) {
                return i;
            }
        }
        return -1;
    }

}
